#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Async TCP dictionary server (English <-> Chinese), UTF-8, line-based protocol.
Protocol:
  - Client sends one UTF-8 line per query:
      "en:apple"  -> English to Chinese
      "zh:苹果"   -> Chinese to English
      "hello"     -> defaults to English->Chinese
  - Server replies with one line:
      "OK <translation>\n" or "ERR NotFound\n" or "ERR BadPrefix(use en:word or zh:词)\n"

Run:
  python server.py --host 0.0.0.0 --port 5555
"""
import argparse
import asyncio
import json
from typing import Dict, Tuple

def to_lower_ascii(s: str) -> str:
    # Only downcase basic ASCII letters; safe for mixed content
    return "".join(chr(ord(c) + 32) if "A" <= c <= "Z" else c for c in s)

def build_dict() -> Tuple[Dict[str, str], Dict[str, str]]:
    # Seed pairs; extend as needed or load from JSON file if provided.
    seed_pairs = [
        ("apple", "苹果"),
        ("banana", "香蕉"),
        ("orange", "橙子"),
        ("hello", "你好"),
        ("world", "世界"),
        ("computer", "电脑"),
        ("harvard", "哈佛大学"),
        ("xjtu", "西安交通大学"),
        ("student", "学生"),
        ("teacher", "老师"),
    ]
    en2zh = {to_lower_ascii(en): zh for en, zh in seed_pairs}
    zh2en = {zh: en for en, zh in seed_pairs}
    return en2zh, zh2en

class DictServer:
    def __init__(self, en2zh: Dict[str, str], zh2en: Dict[str, str]):
        self.en2zh = en2zh
        self.zh2en = zh2en

    def translate(self, line: str) -> str:
        line = line.strip()
        if not line:
            return "ERR BadQuery\n"
        if ":" in line:
            prefix, term = line.split(":", 1)
        else:
            prefix, term = "en", line

        if prefix.lower() == "en":
            term_l = to_lower_ascii(term)
            ans = self.en2zh.get(term_l)
            return f"OK {ans}\n" if ans is not None else "ERR NotFound\n"
        elif prefix.lower() == "zh":
            ans = self.zh2en.get(term)
            return f"OK {ans}\n" if ans is not None else "ERR NotFound\n"
        else:
            return "ERR BadPrefix(use en:word or zh:词)\n"

    async def handle_client(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
        addr = writer.get_extra_info("peername")
        try:
            while True:
                data = await reader.readline()
                if not data:
                    break  # client closed
                try:
                    line = data.decode("utf-8", errors="replace").rstrip("\r\n")
                except Exception:
                    writer.write(b"ERR Decode\n")
                    await writer.drain()
                    continue

                reply = self.translate(line)
                writer.write(reply.encode("utf-8"))
                await writer.drain()
        finally:
            try:
                writer.close()
                await writer.wait_closed()
            except Exception:
                pass

async def main():
    parser = argparse.ArgumentParser(description="Async TCP dictionary server (EN<->ZH)")
    parser.add_argument("--host", default="0.0.0.0", help="bind host (default: 0.0.0.0)")
    parser.add_argument("--port", type=int, default=5555, help="port (default: 5555)")
    args = parser.parse_args()

    en2zh, zh2en = build_dict()
    server = DictServer(en2zh, zh2en)

    srv = await asyncio.start_server(server.handle_client, host=args.host, port=args.port)
    sockets = ", ".join(str(sock.getsockname()) for sock in srv.sockets or [])
    print(f"Server listening on {sockets} ... (UTF-8, line protocol)")

    async with srv:
        await srv.serve_forever()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nServer shutting down.")
